<?php

namespace Itbbn\ThinkphpModelCreater\lib;


use Itbbn\ThinkphpModelCreater\lib\Config;

class TableModelMaker extends Base
{
    /**
     * 主键
     * @var string
     */
    public string $pk = "";
    public string $tableName = "";
    public string $tableRemark = "";
    public bool $isSoftDelete = false;
    public string $softDeleteColumn = "";

    public array $columns = [];

    public string $endOfLine = "\r\n";


    protected function getTypeName($type): string
    {
        // 只保留括号前面的内容
        $type = preg_replace('/\(.*/', '', $type);

        // 类型映射表
        $typeMap = [
            // 整数类型
            'int' => 'int', 'tinyint' => 'int', 'smallint' => 'int',
            'mediumint' => 'int', 'bigint' => 'int', 'timestamp' => 'int',

            // 浮点类型
            'float' => 'float', 'double' => 'float', 'decimal' => 'float', 'bit' => 'float',

            // 字符串类型
            'char' => 'string', 'varchar' => 'string', 'binary' => 'string',
            'varbinary' => 'string', 'tinytext' => 'string', 'text' => 'string',
            'mediumtext' => 'string', 'longtext' => 'string', 'enum' => 'string', 'set' => 'string',

            // 混合类型
            'tinyblob' => 'mixed', 'blob' => 'mixed', 'mediumblob' => 'mixed',
            'longblob' => 'mixed', 'date' => 'mixed', 'datetime' => 'mixed', 'json' => 'mixed',

            // 特殊类型
            'time' => 'time', 'year' => 'year',

            // 空间类型
            'point' => 'point', 'linestring' => 'linestring', 'polygon' => 'polygon',
            'multipoint' => 'multipoint', 'multilinestring' => 'multilinestring',
            'multipolygon' => 'multipolygon',
        ];

        return $typeMap[$type] ?? $type;
    }

    private function formatString($str, $len = 8)
    {
        //格式化字符串，不足长度补空格
        while (strlen($str) < $len) {
            $str = $str . " ";
        }
        return $str;
    }

    /**
     * 获取模型的代码
     * @return string
     */
    public function getCode(): string
    {
        $codeStr = "<?php" . $this->endOfLine;
        $codeStr .= "namespace " . Config::instance()->namespace . ";" . $this->endOfLine;
        $codeStr .= $this->endOfLine;
        $codeStr .= "/**" . $this->endOfLine;
        $codeStr .= " *  auth " . Config::instance()->author . $this->endOfLine;
        //$codeStr .= " *  create-time " . Util::getTime() . $this->endOfLine;
        $codeStr .= " */" . $this->endOfLine;
        $codeStr .= "class " . $this->tableName . " extends " . Config::instance()->baseNamespace . "\\" . $this->tableName . $this->endOfLine;
        $codeStr .= "{" . $this->endOfLine;
        $codeStr .= "}" . $this->endOfLine;

        return $codeStr;
    }

    public function getBaseModelCode(): string
    {
        $codeStr = "<?php" . $this->endOfLine;
        $codeStr .= "namespace " . Config::instance()->namespace . "\\base;" . $this->endOfLine;
        $codeStr .= "use think\\Model;" . $this->endOfLine;;
        $codeStr .= $this->endOfLine;
        $codeStr .= "/**" . $this->endOfLine;
        $codeStr .= " *  auth " . Config::instance()->author . $this->endOfLine;
        //$codeStr .= " *  create-time " . Util::getTime() . $this->endOfLine;
        $codeStr .= " */" . $this->endOfLine;
        $codeStr .= "class " . Config::instance()->baseModel . " extends Model" . $this->endOfLine;
        $codeStr .= "{" . $this->endOfLine;
        if (Config::instance()->connection) {
            //如果设置了连接信息
            $codeStr .= "    protected \$connection = '" . Config::instance()->connection . "';" . $this->endOfLine;
        }
        $codeStr .= "}" . $this->endOfLine;
        return $codeStr;
    }


    /**
     * 获取模型的代码
     * @return string
     */
    public function getBaseCode(): string
    {
        $codeStr = "<?php" . $this->endOfLine;
        $codeStr .= "namespace " . Config::instance()->namespace . "\\base;" . $this->endOfLine;
        $codeStr .= "use " . Config::instance()->namespace . ";" . $this->endOfLine;
        if ($this->isSoftDelete) {
            $codeStr .= "use think\model\concern\SoftDelete;" . $this->endOfLine;
        }
        $codeStr .= $this->endOfLine;
        $codeStr .= "/**" . $this->endOfLine;
        $codeStr .= " *  auth " . Config::instance()->author . $this->endOfLine;
        //$codeStr .= " *  create-time " . Util::getTime() . $this->endOfLine;

        //设置注解
        foreach ($this->columns as $column) {
            $comment = str_replace("\n", "", $column['Comment']);
            $comment = str_replace("\r", "", $comment);
            $codeStr .= " * @property " . $this->formatString($this->getTypeName($column['Type']), 10) . " \$" . $this->formatString($column['Field'], 20) . " " . $comment . $this->endOfLine;
        }
        $codeStr .= ' * @method   self       find($data = null)     找单条记录' . $this->endOfLine;
        $codeStr .= " */" . $this->endOfLine;
        $codeStr .= "class " . $this->tableName . " extends " . Config::instance()->baseModel . $this->endOfLine;
        $codeStr .= "{" . $this->endOfLine;
        if ($this->isSoftDelete) {
            $codeStr .= "    use SoftDelete;" . $this->endOfLine;
        }
        if ($this->pk) {
            $codeStr .= "    protected \$pk = '" . $this->pk . "';" . $this->endOfLine;
        }
        //设置字段
        $codeStr .= "    protected \$schema = [" . $this->endOfLine;
        foreach ($this->columns as $column) {
            $keyStr = "'" . $column['Field'] . "'";
            $typeStr = "'" . $this->getTypeName($column['Type']) . "'";
            $comment = str_replace("\n", "", $column['Comment']);
            $comment = str_replace("\r", "", $comment);
            $codeStr .= "        " . $this->formatString($keyStr, 20) . " => " . $this->formatString($typeStr, 10) . ", //" . $comment . $this->endOfLine;
        }
        $codeStr .= "    ];" . $this->endOfLine;
        $codeStr .= "}" . $this->endOfLine;

        return $codeStr;
    }


    public function getBaseFilePath(): string
    {
        return Config::instance()->modelDir . Config::instance()->baseDir . $this->getFileName();
    }

    /**
     * 获取文件路径
     * @return string
     */
    public function getFilePath(): string
    {
        return Config::instance()->modelDir . $this->getFileName();
    }

    /**
     * 获取文件名
     * @return string
     */
    public function getFileName(): string
    {
        return $this->tableName . ".php";
    }

}